package cn.amossun.starter.web.data.security.handler;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.amossun.starter.common.properties.DataSecurityProperties;
import cn.amossun.starter.web.data.security.IDecryptData;
import cn.amossun.starter.web.data.security.IEncryptData;
import cn.amossun.starter.mybatis.data.security.rule.MybatisDecryptRule;
import cn.amossun.starter.mybatis.data.security.rule.MybatisEncryptRule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @description:
 * @author: Amos.Sun
 * @DateTime: 2020/03/08 15:41
 **/
@Data
@Slf4j
@AllArgsConstructor
public class EncryptDecryptDataHandler implements IDecryptData, IEncryptData {

	private final MybatisDecryptRule mybatisDecryptRule;

	private final MybatisEncryptRule mybatisEncryptRule;

	@Override
	public String handlerDecryptData(String value) throws Exception {
		return mybatisDecryptRule.getDecryptValue(value);
	}

	@Override
	public String handlerEncryptData(String tableName, String value) throws Exception {
		if(checkGrayLevelVersion(tableName) && !isDecryptData(value)) {
			log.info("表: {}, 字段: {} 进入加密.", tableName, value);
			String encryptValue = mybatisEncryptRule.encodeEncryptValue(value);
			log.info("表: {}, 字段: {} 进入值加密.", tableName, encryptValue);
			return encryptValue;
		}
		return value;
	}

	@Override
	public boolean isDecryptData(String originalValue) {
		if(StrUtil.isEmpty(originalValue)) {
			//数据为空默认为已加密 则无需加密处理.
			return true;
		}
		if(mybatisEncryptRule == null) {
			return true;
		}
		DataSecurityProperties properties = mybatisEncryptRule.getProperties();
		if(properties == null) {
			return true;
		}
		//检查是否未配置加密特殊字符前后缀
		if(originalValue.startsWith(properties.getDataBeforeSuffix())
			&& originalValue.endsWith(properties.getDataAfterSuffix())) {
			return true;
		}
		return false;
	}

	@Override
	public String selectEncryptData(String value) throws Exception {
		return mybatisEncryptRule.encodeEncryptValue(value);
	}

	boolean checkGrayLevelVersion(String tableName) {
		try {
			if(StrUtil.isEmpty(tableName)) {
				return false;
			}
			if(CollectionUtil.isEmpty(mybatisEncryptRule.getOrmConfigMap())) {
				return false;
			}
			return mybatisEncryptRule.getOrmConfigMap().containsKey(tableName.toLowerCase());
		} catch (Exception exception) {
			log.error("checkGrayLevelVersion ex: {}.", exception.getMessage());
		}
		return false;
	}

}
